/*
srkrt_dynamic_list.c
Ce fichier contient le corps des fonctions utilisées pour manipuler la liste.
*/
#include "srkrt_dynamic_list.h"
#include <stdlib.h>
#include <stdio.h>

/* ---------------------------------------
	Declaration des fonctions 
--------------------------------------- */

List srkrt_list_create(void) {

	List l;
	l.head = NULL;
	return(l);
}

bool srkrt_list_is_empty(List* l) {

	if ( l == NULL ) {
		fprintf(stderr, "Error in list_is_empty() : list isn't initialized !\n");
	}
	return(l->head == NULL);

}

void srkrt_list_add(List* l, Move m) {

	Cel* new = NULL;
        
	if ( l != NULL ) {
		/* création de la nouvelle cellule */
		new = malloc(sizeof(Cel));
		
		if ( new == NULL ) {
			fprintf(stderr, "Error in list_add() : allocation impossible !\n");
		} else {
			/* on lie la nouvelle cellule au reste de la List */
			new->next = l->head;  

			/* on affecte l'élément */
			new->value = m ;

			/* on lie la List à la nouvelle cellule */
			l->head = new;
			
		}
	} else {
		fprintf(stderr, "Error in list_add() : list isn't initialized !\n");
	}
}

bool srkrt_list_map(bool (*f)(List*, Cel*, Move), List* list, Move m) {
	
	Cel* current;
	Cel* next;
	bool end = false;
	current = list->head;
	
	/* on parcours la liste jusqu'a la fin ou jusqu'a ce que le fonction f passee en parametres renvoie true*/
	while ( (current != NULL) && !end ) {
		/* on applique la fonction à la Cel, si f renvoie true on s'arrète */
		next = current->next;
		end = f(list, current, m);
		/* on passe à la Cel suivante */
		current = next;
	}
	return(end);
}

bool p_is_present(List* l, Cel* cel, Move m) {

	bool isPresent = false;
	if ( ( cel->value.xi == m.xi ) && ( cel->value.yi == m.yi )
		&& ( cel->value.xf == m.xf ) && ( cel->value.yf == m.yf ) ) {
		isPresent = true;
	}
	return(isPresent);
}

bool p_list_remove(List* l, Cel* cel, Move m) {
	
	if ( cel == NULL ) {
		fprintf(stderr, "Error in p_list_remove() : cel not initialized !\n");
	}
	/* on lie la tete de la liste a la deuxieme cel */
	l->head = cel->next;
	/* on supprime la cellule */
	free(cel);

	return(false);
}

void srkrt_list_destroy(List* l) {

	Move m;
	if ( l != NULL ) {
		srkrt_list_map(&p_list_remove, l, m);
	} else {
		fprintf(stderr, "Error in list_destroy() : la liste n'est pas initialise !\n");
	}
}

Iter srkrt_iter_create(List* l) {

	if ( srkrt_list_is_empty(l) ) {
		fprintf(stderr, "Error in srkrt_iter_create() : la liste n'est pas initialise !\n");
	}
	return(l->head);
}

void srkrt_iter_next(Iter* iter) {

	if ( *iter == NULL ) {
		fprintf(stderr, "Error in srkrt_iter_next() : iter pointe vers null, il n'y a pas de suivant !\n");
	}
	/* on fait pointer l'iterateur vers la Cel suivant */
	*iter = (*iter)->next;
}

Move srkrt_iter_get_value(Iter iter) {
	return(iter->value);
}
